package src.model.gameWorld;

import java.util.HashMap;
import java.util.Map;

import src.model.gameObject.*;
import src.model.gameObject.ability.AbilityAttributes;
import src.model.gameObject.ability.AbilityType;

/**
 * <b>Overview</b><br>
 * <p>The PlayerLookupTable performs much like a GlobalLookupTable, 
 * except it has the additional behavior of applying a player specific 
 * modifiers to the statistic values it returns.
 * <br>
 * A Player LookupTable is structured similiarly to a GlobalLookupTable.  
 * When you query for a value from the PlayerLookupTable, it first refers 
 * to the default value in the GlobalLookupTable, then adds its own, 
 * player-specific modifer, then returns the value.  See the 
 * GlobalLookupTable documentation for more details.</p>
 * <br><br>
 * <b>Responsibilites</b><br>
 * <p>The Player Lookup table is responsible for holding the default 
 * statistic values for all of a player's specific PlayerGameObjects, 
 * and producing them when queried.</p>
 * <br><br>
 * <b>Collaborators</b>
 * <ul>
 * <li>LookupTable - Subcontractor</li>
 * </ul>
 * <br><br>
 * <b>Implementor</b> - Brent<br>
 * <b>Tester</b> - Tristan<br>
 * 
 * @author Brent
 *
 */
public class PlayerLookupTable extends LookupTable {

	private Map<AbilityPairing, Float> playerAbilityPairings;
	private Map<GameObjectPairing, Float> playerGameObjectPairings;
	
	public PlayerLookupTable(String filename)
	{
		super(filename);
		
		playerAbilityPairings = new HashMap<AbilityPairing, Float>();
		playerGameObjectPairings = new HashMap<GameObjectPairing, Float>();
	}

	public float statQuery(AbilityType ability, AbilityAttributes stat)
	{
		AbilityPairing ap = new AbilityPairing(ability, stat);
		
		if(!playerAbilityPairings.containsKey(ap))
			playerAbilityPairings.put(ap, 0.0f);
		
		return playerAbilityPairings.get(ap) + super.statQuery(ability, stat);
	}
	
	public float statQuery(GameObjectType gameObjectType, GameObjectSubtype 
			gameObjectSubtype, AbilityType ability, AbilityAttributes stat)
	{
		GameObjectPairing gp = new GameObjectPairing(
				gameObjectType,
				gameObjectSubtype,
				ability,
				stat);
		
		if(!playerGameObjectPairings.containsKey(gp))
			playerGameObjectPairings.put(gp, 0.0f);
		
		return super.statQuery(gameObjectType, gameObjectSubtype, ability, stat) 
			+ playerGameObjectPairings.get(gp);
	}
	
	public float setStat(AbilityType ability, AbilityAttributes stat, float amount)
	{
		AbilityPairing ap = new AbilityPairing(ability, stat);
		
		playerAbilityPairings.put(ap, new Float(amount));
		
		return statQuery(ability, stat);
	}
	
	public float setStat(GameObjectType gameObjectType, GameObjectSubtype gameObjectSubtype,
			AbilityType ability, AbilityAttributes stat, float amount)
	{
		GameObjectPairing gp = new GameObjectPairing(
				gameObjectType,
				gameObjectSubtype,
				ability,
				stat);
		
		amount -= statQuery(ability, stat);
		amount -= super.statQuery(gameObjectType, gameObjectSubtype, ability, stat);
		playerGameObjectPairings.put(gp, amount);
		
		return statQuery(gameObjectType, gameObjectSubtype, ability, stat);
	}
	
	public float modifyStat(AbilityType ability, AbilityAttributes stat, float amount)
	{
		setStat(ability, stat, statQuery(ability, stat) + amount);
		
		return statQuery(ability, stat);
	}
	
	public float modifyStat(GameObjectType gameObjectType, GameObjectSubtype gameObjectSubtype,
			AbilityType ability, AbilityAttributes stat, float amount)
	{
		setStat(gameObjectType, gameObjectSubtype, ability, stat, 
				statQuery(gameObjectType, gameObjectSubtype, ability, stat) + amount);
		
		return statQuery(gameObjectType, gameObjectSubtype, ability, stat);	
	}
}
